﻿using System;
using System.Windows.Forms;

namespace AyuBookmark.WinForm.Commands
{
    /// <summary>
    /// WinForm专用的RelayCommand实现
    /// </summary>
    public class RelayCommand : IRelayCommand
    {
        private readonly Action<object> _execute;
        private readonly Predicate<object> _canExecute;
        private readonly Control _syncContext;

        /// <summary>
        /// 初始化命令
        /// </summary>
        /// <param name="execute">执行逻辑</param>
        /// <param name="canExecute">可用性判断逻辑</param>
        /// <param name="syncContext">UI同步上下文（可选）</param>
        public RelayCommand(
            Action<object> execute,
            Predicate<object> canExecute = null,
            Control syncContext = null)
        {
            _execute = execute ?? throw new ArgumentNullException(nameof(execute));
            _canExecute = canExecute;
            _syncContext = syncContext;
        }

        /// <inheritdoc />
        public bool CanExecute(object parameter)
        {
            try
            {
                return _canExecute?.Invoke(parameter) ?? true;
            }
            catch
            {
                return false;
            }
        }

        /// <inheritdoc />
        public void Execute(object parameter)
        {
            if (_syncContext != null && _syncContext.InvokeRequired)
            {
                _syncContext.Invoke(new Action(() => _execute(parameter)));
            }
            else
            {
                _execute(parameter);
            }
        }

        /// <inheritdoc />
        public event EventHandler CanExecuteChanged;

        /// <inheritdoc />
        public void RaiseCanExecuteChanged()
        {
            if (_syncContext != null && _syncContext.InvokeRequired)
            {
                _syncContext.BeginInvoke(new Action(() =>
                    CanExecuteChanged?.Invoke(this, EventArgs.Empty)));
            }
            else
            {
                CanExecuteChanged?.Invoke(this, EventArgs.Empty);
            }
        }
    }
}